package cn.mujiankeji.mbrowser.界面.组件.代码框

import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.withStyle
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import org.json.JSONTokener
import org.jsoup.Jsoup
import org.jsoup.nodes.Element
import org.jsoup.nodes.Node

/**
 * 代码格式化工具类
 */
object 代码格式化工具 {
    
    /**
     * 将HTML代码转换为代码节点列表
     */
    fun 解析HTML(code: String?): List<代码节点>? {
        if (code.isNullOrEmpty()) return null
        val el = Jsoup.parse(code)
        
        return if (el.head() != null && el.head().childNodeSize() > 0) {
            解析HTML节点(null, el)
        } else {
            解析HTML节点(null, el.body())
        }
    }
    
    /**
     * 只解析HTML的body内容
     */
    fun 解析HTML主体(code: String?): List<代码节点>? {
        return if (code.isNullOrEmpty()) null else 解析HTML节点(null, Jsoup.parse(code).body())
    }
    
    /**
     * 解析HTML节点
     */
    private fun 解析HTML节点(parent: 代码节点?, element: Element?): List<代码节点>? {
        if (element == null) return null
        val nodeList = mutableListOf<代码节点>()
        
        for (node in element.childNodes()) {
            val parsedNode = 解析单个HTML节点(parent, node)
            if (parsedNode != null && !parsedNode.文本?.text.isNullOrBlank()) {
                nodeList.add(parsedNode)
            }
        }
        
        return nodeList
    }
    
    /**
     * 解析单个HTML节点
     */
    private fun 解析单个HTML节点(parent: 代码节点?, node: Node): 代码节点? {
        val codeNode = 代码节点(父节点 = parent)
        
        // 处理文档类型
        if (node.nodeName() == "#doctype") return null
        
        // 处理注释
        if (node.nodeName() == "#comment") {
            codeNode.文本 = buildAnnotatedString {
                withStyle(SpanStyle(color = 代码颜色.注释)) {
                    append("<!--${node.attr("#comment")}-->")
                }
            }
            return codeNode
        } else if (node.nodeName() == "#data") {
            val 数据文本 = node.attr("#data").trim()
            if (数据文本.isBlank()) return null
            
            codeNode.文本 = buildAnnotatedString { append(数据文本) }
            return codeNode
        }
        
        // 处理文本节点
        if (node.nodeName() == "#text") {
            val 文本内容 = node.outerHtml().trim()
            if (文本内容.isBlank()) return null
            
            codeNode.文本 = buildAnnotatedString { append(文本内容) }
            return codeNode
        } else {
            // 处理元素节点
            val text = buildAnnotatedString {
                withStyle(SpanStyle(color = 代码颜色.名称)) {
                    append("<${node.nodeName()}")
                }
                
                // 处理属性
                for ((key, value) in node.attributes()) {
                    append(" ")
                    withStyle(SpanStyle(color = 代码颜色.标签)) {
                        append(key)
                    }
                    append("=\"")
                    withStyle(SpanStyle(color = 代码颜色.文本)) {
                        append(value)
                    }
                    append("\"")
                }
            }
            
            codeNode.文本 = text
            
            // 处理子节点
            if (node.childNodeSize() > 0) {
                // 如果只有一个文本子节点，直接合并
                if (node.childNodeSize() == 1 && node.childNode(0).nodeName() == "#text") {
                    val 子节点文本 = node.childNode(0).outerHtml().trim()
                    if (子节点文本.isBlank()) {
                        // 如果子节点是空白文本，显示为自闭合标签
                        codeNode.文本 = buildAnnotatedString {
                            append(text)
                            withStyle(SpanStyle(color = 代码颜色.名称)) {
                                append("></${node.nodeName()}>")
                            }
                        }
                    } else {
                        val combinedText = buildAnnotatedString {
                            append(text)
                            append(">")
                            append(子节点文本)
                            withStyle(SpanStyle(color = 代码颜色.名称)) {
                                append("</${node.nodeName()}>")
                            }
                        }
                        codeNode.文本 = combinedText
                    }
                } else {
                    // 有多个子节点，需要展开
                    codeNode.子节点列表 = mutableListOf()
                    for (childNode in node.childNodes()) {
                        val childCodeNode = 解析单个HTML节点(codeNode, childNode)
                        if (childCodeNode != null && !childCodeNode.文本?.text.isNullOrBlank()) {
                            codeNode.子节点列表!!.add(childCodeNode)
                        }
                    }
                    
                    // 设置结束标签
                    codeNode.结束文本 = buildAnnotatedString {
                        withStyle(SpanStyle(color = 代码颜色.名称)) {
                            append("</${node.nodeName()}>")
                        }
                    }
                    
                    // 修改开始标签，添加>
                    codeNode.文本 = buildAnnotatedString {
                        append(text)
                        withStyle(SpanStyle(color = 代码颜色.名称)) {
                            append(">")
                        }
                    }
                }
            } else {
                // 没有子节点，自闭合标签
                codeNode.文本 = buildAnnotatedString {
                    append(text)
                    withStyle(SpanStyle(color = 代码颜色.名称)) {
                        if (node.outerHtml().matches(Regex("/[\\s]*?>$"))) {
                            append("/>")
                        } else {
                            append("></${node.nodeName()}>")
                        }
                    }
                }
            }
        }
        
        return if (codeNode.文本?.text.isNullOrBlank()) null else codeNode
    }
    
    /**
     * 解析JSON代码
     */
    fun 解析JSON(code: String): List<代码节点>? {
        if (code.isBlank()) return null
        
        try {
            // 判断是否为HTML中的pre标签包裹的JSON
            return if (code.matches(Regex("^[\\n|\\s]*<pre.*?</pre>[\\n|\\s]*$"))) {
                val jsonText = Jsoup.parse(code).body().child(0).html()
                解析JSON对象(null, JSONObject(jsonText))
            } else {
                val obj = JSONTokener(code).nextValue() ?: return null
                解析JSON对象(null, obj)
            }
        } catch (e: JSONException) {
            e.printStackTrace()
        }
        return null
    }
    
    /**
     * 解析JSON对象
     */
    private fun 解析JSON对象(parent: 代码节点?, obj: Any): MutableList<代码节点>? {
        try {
            val nodeList = mutableListOf<代码节点>()
            
            when (obj) {
                is JSONArray -> {
                    val array = obj
                    for (i in 0 until array.length()) {
                        val value = array[i]
                        val node = 代码节点(父节点 = parent)
                        
                        // 设置索引为属性名
                        node.属性名 = i.toString()
                        node.属性值 = value
                        
                        if (value is JSONObject || value is JSONArray) {
                            // 复杂类型，需要展开
                            node.子节点列表 = 解析JSON对象(node, value)
                            
                            // 设置文本
                            node.文本 = buildAnnotatedString {
                                withStyle(SpanStyle(color = 代码颜色.键)) {
                                    append("[$i]: ")
                                }
                                
                                withStyle(SpanStyle(color = 代码颜色.值)) {
                                    append(if (value is JSONObject) "{...}" else "[...]")
                                }
                            }
                        } else {
                            // 简单类型，直接显示值
                            node.文本 = buildAnnotatedString {
                                withStyle(SpanStyle(color = 代码颜色.键)) {
                                    append("[$i]: ")
                                }
                                
                                withStyle(SpanStyle(color = 代码颜色.值)) {
                                    append(value?.toString() ?: "null")
                                }
                            }
                        }
                        
                        nodeList.add(node)
                    }
                }
                is JSONObject -> {
                    val jsonObject = obj
                    val keys = jsonObject.keys()
                    
                    while (keys.hasNext()) {
                        val key = keys.next()
                        val value = jsonObject[key]
                        val node = 代码节点(父节点 = parent)
                        
                        node.属性名 = key
                        node.属性值 = value
                        
                        if (value is JSONObject || value is JSONArray) {
                            // 复杂类型，需要展开
                            node.子节点列表 = 解析JSON对象(node, value)
                            
                            // 设置文本
                            node.文本 = buildAnnotatedString {
                                withStyle(SpanStyle(color = 代码颜色.键)) {
                                    append("\"$key\": ")
                                }
                                
                                withStyle(SpanStyle(color = 代码颜色.值)) {
                                    append(if (value is JSONObject) "{...}" else "[...]")
                                }
                            }
                        } else {
                            // 简单类型，直接显示值
                            node.文本 = buildAnnotatedString {
                                withStyle(SpanStyle(color = 代码颜色.键)) {
                                    append("\"$key\": ")
                                }
                                
                                withStyle(SpanStyle(color = 代码颜色.值)) {
                                    if (value is String) {
                                        append("\"${value}\"")
                                    } else {
                                        append(value?.toString() ?: "null")
                                    }
                                }
                            }
                        }
                        
                        nodeList.add(node)
                    }
                }
            }
            
            return nodeList
        } catch (e: JSONException) {
            e.printStackTrace()
            return null
        }
    }
    
    /**
     * 创建折叠文本
     */
    fun 创建折叠文本(text: AnnotatedString?, endText: AnnotatedString?): AnnotatedString {
        return buildAnnotatedString {
            if (text != null) {
                append(text)
            }
            append("...")
            if (endText != null) {
                append(endText)
            }
        }
    }
} 